package shake.el;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import shake.annotation.Component;
import shake.context.ThreadLocalObject;

import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
@Component
public class ELVariable {
	@Inject
	ThreadLocalObject<LinkedList<Map<String, Object>>> stack;

	public Object get(String name) {
		LinkedList<Map<String, Object>> s = getStack();
		for (int i = s.size() - 1; i >= 0; i--) {
			Object o = s.get(i).get(name);
			if (o != null) {
				return o;
			}
		}
		return null;
	}

	public Object put(String name, Object obj) {
		return getMap().put(name, obj);
	}

	public void push(Map<String, Object> map) {
		getStack().addLast(map);
	}

	public Map<String, Object> pop() {
		return getStack().removeLast();
	}

	private Map<String, Object> getMap() {

		LinkedList<Map<String, Object>> s = getStack();
		if (s.size() == 0) {
			s.add(new HashMap<String, Object>());
		}
		return s.getLast();
	}

	private LinkedList<Map<String, Object>> getStack() {
		LinkedList<Map<String, Object>> s = stack.get();
		if (s == null) {
			s = new LinkedList<Map<String, Object>>();
			stack.set(s);
		}
		return s;
	}
}
